/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package exterminator.levels;

import com.jme3.collision.CollisionResult;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.math.Vector4f;
import exterminator.Main;
import exterminator.utils.AudioManager;
import exterminator.utils.TextureManager.RegionKey;
import exterminator.utils.TextureManager.TextureKey;
import java.util.ArrayList;
import java.util.List;
import tonegod.gui.controls.buttons.ButtonAdapter;
import tonegod.gui.core.Element;
import tonegod.gui.core.ElementManager;
import tonegod.gui.core.Screen;
import tonegod.gui.core.SubScreen;
import tonegod.gui.core.utils.UIDUtil;
import tonegod.gui.framework.core.util.GameTimer;

/**
 *
 * @author t0neg0d
 */
public class Deck {
	List<Bug> bugs = new ArrayList();
	List<Muck> mucks = new ArrayList();
	
	Element elMucks, elBugs;
	
	int deckIndex;
	Main main;
	Screen screen;
	Levels levels;
	
	int bugCount = 0;
	
	public Deck(Main main, Levels levels, int deckIndex) {
		this.main = main;
		this.screen = main.getScreen();
		this.deckIndex = deckIndex;
		this.levels = levels;
	}
	
	public void populateDeck() {
		elMucks = new Element(getSubScreen(), UIDUtil.getUID(), Vector2f.ZERO, levels.getDeckDimensions(deckIndex), Vector4f.ZERO, null);
		elMucks.setIgnoreMouse(true);
		elMucks.setEffectZOrder(false);
		
		elBugs = new Element(getSubScreen(), UIDUtil.getUID(), Vector2f.ZERO, levels.getDeckDimensions(deckIndex), Vector4f.ZERO, null);
		elBugs.setIgnoreMouse(true);
		elBugs.setEffectZOrder(false);
		
		getSubScreen().addElement(elMucks);
		getSubScreen().addElement(elBugs);
		
	//	elMucks.setAsContainerOnly();
	//	elBugs.setAsContainerOnly();
	}
	
	public Element getElMucks() { return this.elMucks; }
	
	public Element getElBugs() { return this.elBugs; }
	
	public SubScreen getSubScreen() { return levels.getDeckSubScreen(deckIndex); }
	
	public List<Muck> getMucks() { return this.mucks; }
	
	public void addMuck(Vector2f pos) {
		float size = 25+(FastMath.nextRandomFloat()*75);
		
		Muck muck = new Muck(
			levels.getDeckSubScreen(deckIndex),
			Vector2f.ZERO,
			new Vector2f(size,size)
		);
		
		mucks.add(muck);
		
	//	levels.getDeckSubScreen(deckIndex).addElement(muck);
		elMucks.addChild(muck);
		muck.setPosition(pos);
	}
	
	public void removeMuck(Muck muck) {
		mucks.remove(muck);
	}
	
	public void clearMuck() { mucks.clear(); }
	
	public List<Bug> getBugs() { return this.bugs; }
	public int getBugCount() { return this.bugCount; }
	
	public void releaseBug() {
		Vector2f dim = levels.getDeckDimensions(deckIndex);
		float randX = FastMath.nextRandomFloat()*dim.x;
		float randY = FastMath.nextRandomFloat()*dim.y;
		
		float ratio = 100f/158f;
		float size = 40+(FastMath.nextRandomFloat()*80);
		
		Bug bug = new Bug(
			levels.getDeckSubScreen(deckIndex),
			new Vector2f(randX,randY),
			new Vector2f(size,size*ratio)
		);
		
		bugs.add(bug);
	//	levels.getDeckSubScreen(deckIndex).addElement(bug);
		elBugs.addChild(bug);
		bugCount++;
		main.getHUD().updateBugCount(deckIndex, bugCount);
	}
	
	public void removeBug(Bug bug) {
		bugs.remove(bug);
		addMuck(bug.getPosition());
		bugCount--;
		main.getHUD().updateBugCount(deckIndex, bugCount);
	}
	
	public void clearBugs() { bugs.clear(); }
	
	public class Bug extends ButtonAdapter {
		private int life = 3;
		private boolean isAlive = true;
		private boolean isMoving = false;
		private Vector2f current = new Vector2f(),
						destination = new Vector2f(),
						step = new Vector2f();
		private Vector3f look = new Vector3f();
		private Vector2f tempV2a = new Vector2f();
		private GameTimer moveTimer;
		private String[] curses = new String[] {
			"@$#!",
			"%$&@#!!",
			"#@!$",
			"%$!#@&",
			"!&#$@!"
		};
		
		public Bug(ElementManager screen, Vector2f pos, Vector2f dim) {
			super(screen, UIDUtil.getUID(), pos, new Vector2f(dim.x/2,dim.y), Vector4f.ZERO, null);
			
			setEffectZOrder(false);
			
			life = 1; //FastMath.nextRandomInt(1,3);
			
			moveTimer = new GameTimer() {
				@Override
				public void onComplete(float time) {
					setIsMoving(false);
				}
			};
			
			this.setTextureAtlasImage(
				main.getTextureManager().getTexture(TextureKey.ATLAS),
				main.getTextureManager().getGUIRegion(RegionKey.BUG)
			);
			clearAltImages();
			
			getGeometry().center();
			
			setLocalRotation(getLocalRotation().fromAngleAxis(FastMath.nextRandomFloat()*360*FastMath.DEG_TO_RAD, Vector3f.UNIT_Z));
		}
		
		@Override
		public void onButtonMouseLeftDown(MouseButtonEvent evt, boolean toggled) {
			if (!main.getHose().isActive())
				whack();
		}
		
		public boolean getIsAlive() { return this.isAlive; }
		
		public void whack() {
			life--;
			CollisionResult result = screen.getLastCollision();
			if (result.getGeometry() == levels.getDeckSubScreen(deckIndex).getGeometry()) {
				main.getEffects().addTextEffect(curses[FastMath.nextRandomInt(0, curses.length-1)],result.getContactPoint(), new ColorRGBA(1,0.7f,0,1), true);
				main.getEffects().addSplashEffect(result.getContactPoint(), ColorRGBA.Green);
			}
			
			if (life == 0) {
				main.getHUD().incGameMeter(1);
				String nKey = "SPLAT_" + String.valueOf(FastMath.nextRandomInt(1,3));
				main.getAudioManager().playAudio(AudioManager.FXKey.valueOf(nKey), 0.5f);
				nKey = "BUG_" + String.valueOf(FastMath.nextRandomInt(1,6));
				main.getAudioManager().playAudio(AudioManager.FXKey.valueOf(nKey), 0.5f);
				isAlive = false;
			}
		}
		
		public void setIsMoving(boolean isMoving) {
			this.isMoving = isMoving;
		}
		
		public void moveBug() {
			if (!isMoving) {
				current.set(getPosition());
				destination.set(
					FastMath.nextRandomFloat()*levels.getDeckDimensions(deckIndex).x,
					FastMath.nextRandomFloat()*levels.getDeckDimensions(deckIndex).y
				);
				moveTimer.reset(false);
				screen.getAnimManager().addGameTimer(moveTimer);
				isMoving = true;
			} else {
				step.interpolate(current, destination, moveTimer.getPercentComplete());
				setPosition(step);
				setLocalRotation(getLocalRotation().fromAngleAxis(getRotation()*FastMath.DEG_TO_RAD,Vector3f.UNIT_Z));
			}
		}
		
		private float getRotation() {
			tempV2a.set(destination.x-current.x,destination.y-current.y).normalizeLocal();
			float angle = FastMath.atan2(tempV2a.y, tempV2a.x)*FastMath.RAD_TO_DEG;
			angle -= 90;
			return angle;
		}
	}
	
	public class Muck extends ButtonAdapter {
		private int maxLife;
		private int life;
		private boolean hoseFocus = false;
		private boolean isAlive = true;
		private int score;
		
		public Muck(ElementManager screen, Vector2f pos, Vector2f dim) {
			super(screen, UIDUtil.getUID(), pos, dim, Vector4f.ZERO, null);
			
			setEffectZOrder(false);
			
			score = FastMath.nextRandomInt(3, 10);
			main.getHUD().incMuckMeter(score);
			
			maxLife = levels.maxMuckLife;
			life = maxLife;
			
			this.setTextureAtlasImage(
				main.getTextureManager().getTexture(TextureKey.ATLAS),
				main.getTextureManager().getGUIRegion(RegionKey.SPLAT)
			);
			clearAltImages();
			
			getGeometry().center();
			
			setLocalRotation(getLocalRotation().fromAngleAxis(FastMath.nextRandomFloat()*360*FastMath.DEG_TO_RAD, Vector3f.UNIT_Z));
		}
		
		@Override
		public void onButtonFocus(MouseMotionEvent evt) {
			hoseFocus = true;
		}
		
		@Override
		public void onButtonLostFocus(MouseMotionEvent evt) {
			hoseFocus = false;
		}
		
		public boolean getHoseFocus() {
			return hoseFocus;
		}
		
		public boolean getIsAlive() { return this.isAlive; }
		
		public void decLife() {
			if (isAlive) {
				if (life > 0) {
					life--;
					float val = 1f/(float)maxLife;
					val = life*val;
					ColorRGBA color = ColorRGBA.White.clone();
					color.a = val;
					getElementMaterial().setColor("Color", color);
				} else {
					CollisionResult result = screen.getLastCollision();
					if (result.getGeometry() == levels.getDeckSubScreen(deckIndex).getGeometry()) {
						main.getEffects().addTextEffect("-" + score,result.getContactPoint(), new ColorRGBA(0,0.7f,1,1), false);
					}
					main.getAudioManager().playAudio(AudioManager.FXKey.CHIME, 0.5f);
					main.getHUD().decMuckMeter(score);
					isAlive = false;
				}
			}
		}
	}
}
